---
title: Mocking schema capabilities
description: Start on client-side features before your server supports them
---

If your GraphQL server doesn't yet support a field that your client will use, you can still start building against that field by mocking its behavior within the client.

For example, let's say we want to add a feature to the Space Explorer app from [the full-stack quickstart course](https://www.apollographql.com/tutorials/fullstack-quickstart/introduction). Specifically, we want to display a description of the rocket used for each launch. To support this functionality on the server side, we'll add a `description` field to our schema's `Rocket` type:

```graphql {5}
type Rocket {
  id: ID!
  name: String
  type: String
  description: String # field not yet supported
}
```

But what if our back-end team isn't finished adding support for the `description` field? By mocking the field's behavior, we can still start developing the feature in our client. To do so, we'll follow the steps below.

## 1. Define a `read` function

Our client app doesn't yet know how to populate the `Rocket.description` field. To fix this, we can define a [`read` function](../caching/cache-field-behavior/#the-read-function) for the field. The Apollo Client cache calls this function whenever the field is queried, and the function's return value is used as the field's value.

Let's define our `read` function in the configuration object we provide to the `InMemoryCache` constructor:

```js {5-9} title="index.js"
const cache = new InMemoryCache({
  typePolicies: {
    Rocket: {
      fields: {
        description: {
          read() {
            // Read function for Rocket.description
            return "Placeholder rocket description";
          },
        },
      },
    },
  },
});
```

This enables us to query the field, but we might not want to show the same boilerplate description for every rocket. To add variety to our mocked output, we can use a library like [faker.js](https://github.com/faker-js/faker):

```js title="index.js"
import { faker } from "@faker-js/faker";

// Returns 1 or 2 sentences of Lorem Ipsum
const oneOrTwoSentences = () =>
  faker.lorem.sentences(Math.random() < 0.5 ? 1 : 2);
```

We can then update our `read` function like so:

```js
// (within InMemoryCache constructor)
read() {
  return oneOrTwoSentences();
}
```

> Make sure to include libraries like faker.js only in your development build, because they can needlessly increase your production bundle size.

## 2. Query with the `@client` directive

We're ready to execute a query that includes our new field. Here's an abridged `GET_LAUNCH_DETAILS` query from the [full-stack quickstart](https://www.apollographql.com/tutorials/fullstack-quickstart/fetching-data-with-queries) with our `description` field added:

```jsx {7}
export const GET_LAUNCH_DETAILS = gql`
  query LaunchDetails($launchId: ID!) {
    launch(id: $launchId) {
      site
      rocket {
        type
        description @client
      }
    }
  }
`;
```

Notice that this field includes the `@client` directive. This directive tells Apollo Client _not_ to include `description` in the query it sends to our server. This is important for two related reasons:

- The `description` field is populated entirely locally, so including it in network requests isn't helpful.
- The `description` field _isn't_ in our server-side schema yet, so including it will produce a GraphQL error.

We can now execute this query in a component with the `useQuery` hook as usual:

```jsx
export default function LaunchDetails({ launchId }) {
  const { data } = useQuery(GET_LAUNCH_DETAILS, { variables: { rocketId } });
  return (
    <div>
      <p>Rocket Type: {data.launch.rocket.type}</p>
      <p>Description: {data.launch.rocket.description}</p>
    </div>
  );
}
```

## 3. Use live data when ready

When your server's support for the `Rocket.description` field is ready, you can begin using it by doing the following:

1. Remove the `@client` directive from `description` in every query that includes it.
2. Remove the field's `read` function (or modify the function so that it uses the current cached value instead of a random string).

---

For more information on the Apollo Client features used here, see the following:

- [Local-only fields](../local-state/managing-state-with-field-policies/)
- [The `read` function](../caching/cache-field-behavior/#the-read-function)
